﻿/*
 * Lop Layer
 * Thuc hien viec lay giao cua mat phang cat va doi tuong theo tung lop
 * Sap xep cac diem thuoc mat phang cat thanh contour kin
 * Tao be mat luoi cac diem chay dao
 */

using System.IO;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Navigation;
using System.Collections.ObjectModel;
using System.Windows.Input;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Documents;
using System.Windows.Shapes;
using System.Windows.Media.Media3D;
using System.Collections;
using System.Data;
using System.Diagnostics;
using Data;
using System;
using Layer;
namespace Layer
{

     public class LayerSlicing :CPoint3D
    {
         
         public  Point3D detectPointEOC = new Point3D(-8888,-8888,-8888); // diem nhan dang ket thuc contour
         public  Point3D detectPoint = new Point3D(-1111, -1111, -1111); // diem nhan dang giao giua duong thang cat va contour
         public  const int CONSTANT_ROUND = 6;// Quy uoc hang so lam tron
         public List<Line3D> line3D_list;// Danh sach duong thang thuoc giao be mat cat va doi tuong
         public  List<Point3D> point3D_list;// Danh sach diem tai moi contour
         public List<REALPOINT> poly;// Danh sach diem 2D cho tat cac mat cac(bao gom ca diem thuoc luoi)
         public List<Point3D> final3D_list;// Danh sach diem 3D cho tat cac mat cac(su dung trong viec luu file SLC)
         public List<Point3D> model_point_list;// Danh sach diem cat thuoc doi tuong(khong bao gom diem thuoc luoi, su dung trong viec hien thi doi tuong cat)


        public LayerSlicing() 
        {
            line3D_list = new List<Line3D>();
            point3D_list = new List<Point3D>();
            poly = new List<REALPOINT>();
            final3D_list = new List<Point3D>();
            model_point_list = new List<Point3D>();
         
        }
        /// <summary>
        /// lay danh sach duong thang 
        /// </summary>
        /// <returns></returns>
        public List<Line3D> GetLine3DList()
        {
            return line3D_list;
        }
        /// <summary>
        /// lay so luong diem thuoc danh sach diem(luoi + contour)-diem thuoc tat cac cac mat cat
        /// </summary>
        /// <returns>So luong diem</returns>
        
        public int GetPointNumber()
        {
            return final3D_list.Count;
        }

        /// <summary>
        /// lay tat ca diem thuoc contour(khong bao gom cac diem thuoc luoi)
        /// </summary>
        /// <returns></returns>
        public  List<Point3D> GetListPoint()
        {
            return model_point_list;    
        }
        /// <summary>
        /// lay diem thu i trong danh sach diem thuoc tat cac cac mat cat
        /// </summary>
        /// <param name="i">Gia tri i tuong ung</param>
        /// <returns></returns>
        public Point3D GetPoint(int i)
        {
            return GetListPoint()[i];
        }
        /// <summary>
        /// lay tat ca danh sach diem (luoi + contour)
        /// </summary>
        /// <returns>Danh sach cac diem tren tat ca be mat cat</returns>
        public List<Point3D> GetGridPointList()
        {
            return final3D_list;
        }
        
        /// <summary>
        /// Cat lop cac doi tuong 
        /// </summary>
        /// <param name="model_list">Danh sach cac doi tuong</param>
        /// <param name="thickness">Do day cho tung lop</param>
        /// <param name="dm">Khoang cach luoi</param>
         public void CreateData(Data.Model3D model_list, double thickness, double dm, double x_lenght, double y_lenght)
        {
            
            int i = 0, j = 0,N;
            N=model_list.GetModelNumber();// lay so luong cac doi tuong can cat
            double zmax = model_list.Zmax();
            double zmin = model_list.Zmin();
            double dz = 0;
            List<Point3D>grid=new List<Point3D>();
            for (dz = zmin; dz <= zmax; dz = dz + thickness)// tai tung gia tri cat
            {
                for (i = 0; i < N; i++)// duyet het tat ca doi tuong tai tung gia tri z
                {
                    if (dz >= model_list.list_mesh3D[i].Zmin() && dz <= model_list.list_mesh3D[i].Zmax())
                    {
                       line3D_list.AddRange( SliceZ(model_list.GetModel(i), dz));// cat lop theo dz, gia tri duoc luu vao linelist.  
                       Debug.WriteLine("[CreateData] >> dz = {0}",dz);
                    }
                }
                if (line3D_list.Count > 0) // if qua trinh cat lop thanh cong
                {
                    SortContour(line3D_list);// xap sep cac contour, gia tri luu vao point3D_list va poly
                    Create_Grid(poly, dm, x_lenght, y_lenght, grid, dz);// tao luoi tai tung gia tri dz,tap hop diem luu vao grid
                    final3D_list.AddRange(point3D_list);//add danh sach diem thuoc con tour
                    final3D_list.AddRange(grid);//add danh sach diem thuoc luoi 

                    model_point_list.AddRange(point3D_list);//add danh sach diem cua contour gianh cho viec hien thi doi tuong duoc cat
                    //clear linelist,poly va pointlist de thuc hien cho lop cat tiep theo
                    grid.Clear();
                    line3D_list.Clear();
                    poly.Clear();
                    point3D_list.Clear();
                }
                
            }
                             
        }
        
        
     
        // Building some necessary functions for Creating grid of stl file
        /*
        public string testing()
        {
            List<REALPOINT> polygon = new List<REALPOINT>();
            List<Point3D> arraypoint = new List<Point3D>();
            
            REALPOINT a1 = new REALPOINT();

                       
            a1.x = 20; a1.y = 10;
            polygon.Add(a1);
            a1.x = 20; a1.y = 30;
            polygon.Add(a1);
            a1.x = 40; a1.y = 30;
            polygon.Add(a1);
            a1.x = 40; a1.y = 10;
            polygon.Add(a1);
            a1.x = 20; a1.y = 10;
            polygon.Add(a1);

            
            a1.x = 133; a1.y = 133;
            polygon.Add(a1);
            a1.x = 133; a1.y = 190;
            polygon.Add(a1);
            a1.x = 190; a1.y = 190;
            polygon.Add(a1);
            a1.x = 190; a1.y = 133;
            polygon.Add(a1);
            a1.x = 133; a1.y = 133;
            polygon.Add(a1);

            a1.x = 80; a1.y = 15;
            polygon.Add(a1);
            a1.x = 80; a1.y = 40;
            polygon.Add(a1);
            a1.x = 120; a1.y = 40;
            polygon.Add(a1);
            a1.x = 120; a1.y = 15;
            polygon.Add(a1);
            a1.x = 80; a1.y = 15;
            polygon.Add(a1);
            

            return "";
        }
         */
        /// <summary>
        /// ham thuc hien tim giao diem duong thay y=dy voi polygons
        /// </summary>
        /// <param name="polygon">Danh sach polygon</param>
        /// <param name="dy">Khoang cac dy</param>
        /// <param name="wy">Work space theo y</param>
        /// <returns></returns>
         public List<Point3D> HoriIntersect(List<REALPOINT> polygon, double dy, double wy, double z)
        {
            List<Point3D> TempArray = new List<Point3D>();
            int i = 0, N;
            N = polygon.Count;

            REALPOINT start;
            REALPOINT a1 = new REALPOINT();
            start = new REALPOINT(polygon[0].x, polygon[0].y);
            TempArray.Add(new Point3D(0, dy,z));// add diem tren truc y
            for (i = 1; i < N; i++)// duyet contour de xac dinh giao diem theo phuong ngang
            {

                if (start.x != polygon[i].x || start.y != polygon[i].y)// khi chua gap diem ket thuc contour
                {
                    double first = polygon[i].y - dy;
                    double last = polygon[i - 1].y - dy;
                    if (first == 0 && last == 0)
                    {
                        if (polygon[i - 1].x != TempArray[TempArray.Count - 1].X)

                            TempArray.Add(new Point3D( polygon[i - 1].x, polygon[i - 1].y,z));
                        if (polygon[i].x != TempArray[TempArray.Count - 1].X)

                            TempArray.Add(new Point3D(polygon[i].x, polygon[i ].y, z));



                    }
                    else if (Math.Sign(first) != Math.Sign(last))
                    {


                        a1.y = dy;
                        a1.x = ((dy - polygon[i].y) * (polygon[i].x - polygon[i - 1].x)) / (polygon[i].y - polygon[i - 1].y) + polygon[i].x;

                        if (a1.x != TempArray[TempArray.Count - 1].X)
                            TempArray.Add(new Point3D( a1.x,a1.y,z));// them vao mang tam.
                    }

                }
                if (start.x == polygon[i].x && start.y == polygon[i].y)
                {
                    double first = polygon[i].y - dy;
                    double last = polygon[i - 1].y - dy;
                    if (first == 0 && last == 0)
                    {
                        if (polygon[i - 1].x != TempArray[TempArray.Count - 1].X)

                            TempArray.Add(new Point3D(polygon[i - 1].x, polygon[i - 1].y, z));
                        if (polygon[i].x != TempArray[TempArray.Count - 1].X)

                            TempArray.Add(new Point3D(polygon[i].x, polygon[i].y, z));



                    }
                    else if (Math.Sign(first) != Math.Sign(last))
                    {


                        a1.y = dy;
                        a1.x = ((dy - polygon[i].y) * (polygon[i].x - polygon[i - 1].x)) / (polygon[i].y - polygon[i - 1].y) + polygon[i].x;

                        if (a1.x != TempArray[TempArray.Count - 1].X)
                            TempArray.Add(new Point3D(a1.x, a1.y, z));// them vao mang tam.// them vao mang tam.
                    }
                    // xu li phu
                    try
                    {
                        i = i + 1;
                        start = polygon[i];
                    }
                    catch { }


                }

            }
            TempArray.Add(new Point3D(wy, dy,z));// add diem tren truc y

            return TempArray;
        }
         /// <summary>
         /// Ham thuc hien tim giao diem duong thang x=dx voi polygon
         /// </summary>
         /// <param name="polygon">Danh sach diem thuoc polygon</param>
         /// <param name="dx">khoang cach dx</param>
         /// <param name="wx">work space theo x</param>
         /// <returns></returns>
         public List<Point3D> VertiIntersect(List<REALPOINT> polygon, double dx, double wx, double z)
       {
           List<Point3D> TempArray = new List<Point3D>();
           int i = 0, N;
           N = polygon.Count;

           REALPOINT start;
           REALPOINT a1 = new REALPOINT();
           start = new REALPOINT(polygon[0].x, polygon[0].y);
           TempArray.Add(new Point3D(dx,0,z));// add diem tren truc x
           for (i = 1; i < N; i++)// duyet contour de xac dinh giao diem 
           {

               if (start.x != polygon[i].x || start.y != polygon[i].y)// khi chua gap diem ket thuc contour
               {
                   double first = polygon[i].x - dx;
                   double last = polygon[i - 1].x - dx;
                   if (first == 0 && last == 0)
                   {
                       if (polygon[i - 1].y != TempArray[TempArray.Count - 1].Y)// xem xet diem trung lap
                           TempArray.Add(new Point3D(polygon[i - 1].x, polygon[i - 1].y, z));

                       if (polygon[i].y != TempArray[TempArray.Count - 1].Y)// xem xet diem trung lap
                           TempArray.Add(new Point3D(polygon[i].x, polygon[i].y, z));



                   }
                   else if (Math.Sign(first) != Math.Sign(last))
                   {


                       a1.x = dx;
                       a1.y = (dx - polygon[i].x) * (polygon[i].y - polygon[i - 1].y) / (polygon[i].x - polygon[i - 1].x) + polygon[i].y;

                       if (a1.y != TempArray[TempArray.Count - 1].Y)// xem xet diem trung lap
                           TempArray.Add(new Point3D(a1.x, a1.y, z));// them vao mang tam.
                   }

               }
               if (start.y == polygon[i].y && start.x == polygon[i].x)
               {
                   double first = polygon[i].x - dx;
                   double last = polygon[i - 1].x - dx;
                   if (first == 0 && last == 0)
                   {
                       if (polygon[i - 1].y != TempArray[TempArray.Count - 1].Y)// xem xet diem trung lap
                           TempArray.Add(new Point3D(polygon[i - 1].x, polygon[i - 1].y, z));

                       if (polygon[i].y != TempArray[TempArray.Count - 1].Y)// xem xet diem trung lap
                           TempArray.Add(new Point3D(polygon[i].x, polygon[i].y, z));



                   }
                   else if (Math.Sign(first) != Math.Sign(last))
                   {


                       a1.x = dx;
                       a1.y = (dx - polygon[i].x) * (polygon[i].y - polygon[i - 1].y) / (polygon[i].x - polygon[i - 1].x) + polygon[i].y;

                       if (a1.y != TempArray[TempArray.Count - 1].Y)// xem xet diem trung lap
                           TempArray.Add(new Point3D(a1.x, a1.y, z));// them vao mang tam.
                   }
                   // xu li phu

                   i = i + 1;
                   try
                   {
                       start = polygon[i];
                   }
                   catch
                   {

                   }


               }

           }
           TempArray.Add(new Point3D(dx, wx,z));// sau khi chay het mot duong thi add them diem ngoai cung 

           return TempArray;
       }
        
       /// <summary>
       /// Xap xep cac doan thang sau khi cat de tao contour kin
       /// </summary>
       /// <param name="line3D_list">Danh sach doan thang</param>
  
       public void SortContour(List<Line3D> line3D_list)
       {

           Point3D start, end;//cac diem xac dinh cho mot doan thang
           //Point3D point = new Point3D();
           start = new Point3D(); end = new Point3D();
           Line3D line = new Line3D();
           start = line3D_list[0].P2;// diem dau contour
           end = line3D_list[0].P1;// diem cuoi contour
           detectPointEOC.Z = start.Z;
           point3D_list.Add(detectPointEOC);// add diem E dau tien de xac dinh diem dat dao
           point3D_list.Add(end);// add doan thang dau tien vao danh sach diem thuoc contour
           poly.Add(new REALPOINT(end.X, end.Y));

           //point = start;
           point3D_list.Add(start);
           poly.Add(new REALPOINT(start.X, start.Y));

           line3D_list[0].SetScaned(true);

           int j = 0, i = 0;


           for (i = 0; i < line3D_list.Count; i++)// duyet tao tung contour
           {
               line = new Line3D();
               line = line3D_list[i];
               if (line.NotScaned() == false)
               {
                   if (start == end)// Khi contour khep kin
                   {
                       Debug.WriteLine("[Z = {0}]Xuat hien diem ket thuc contour ",start.Z);
                       end = line.P1;
                       start = line.p2;
                       point3D_list.Add(detectPointEOC);
                       point3D_list.Add(end);
                       poly.Add(new REALPOINT(end.X, end.Y));

                       //point= start;
                       point3D_list.Add(start);
                       poly.Add(new REALPOINT(start.X, start.Y));
                  
                       line.SetScaned(true);
                       i = 0;

                   }
                   else if (start == line.P1)
                   {
                       start = line.P2;
                      // point = new Point3D();
                     //  point = start;

                       point3D_list.Add(start);
                       poly.Add(new REALPOINT(start.X, start.Y));

                       line.SetScaned(true);
                       i = 0;

                   }
                   else if (start == line.P2)
                   {
                       start = line.P1;
                      // point = new Point3D();
                      // point = start;

                       point3D_list.Add(start);
                       poly.Add(new REALPOINT(start.X, start.Y));

                       line.SetScaned(true);
                       i = 0;
                   }
               }
           }// end of loop
           point3D_list.Add(detectPointEOC); // them diem vao contour cuoi cung truoc khi chay luoi
       } // End of function

       /// <summary>
       /// Thuc hien cat doi tuong tai gia tri Z(giao doi tuong va mat phang(0,0,z))
       /// </summary>
       /// <param name="model_list">Danh sach cac doi tuong</param>
       /// <param name="Z">Gia tri Z</param>
       /// <returns>Danh sach cac duong thang</returns>
 
       public List<Line3D> SliceZ(Mesh3D model_list, double Z)
       {
           // tu vi tri Z xac dinh mang cac doan thang giao nhau.
           // Ket qua tra ve la danh sach cac duong thang.   

           List<Line3D> line_list = new List<Line3D>();
           double side1, side2, side3;
           double x2, x1, y2, y1;
           Point3D p1, p2;
           Line3D line = new Line3D();
           Triangle3D tri = new Triangle3D();
           for (int i = 0; i < model_list.list_triangle.Count; i++)
           {
               tri = model_list.GetTriangle(i);
               side1 = tri.V1.Z - Z;
               side2 = tri.V2.Z - Z;
               side3 = tri.V3.Z - Z;
               line = new Line3D();
               if ((Math.Sign(side1) != Math.Sign(side2)) && (Math.Sign(side1) != Math.Sign(side3)) && (side1 != 0))
               {
                   
                   x1 = tri.V1.X - side1 * (tri.V2.X - tri.V1.X) / (side2 - side1);
                   y1 = tri.V1.Y - side1 * (tri.V2.Y - tri.V1.Y) / (side2 - side1);
                   p1 = new Point3D(x1, y1, Z);
                   line.P1 = p1;
                   
                   x2 = tri.V1.X - side1 * (tri.V3.X - tri.V1.X) / (side3 - side1) ;
                   y2 = tri.V1.Y - side1 * (tri.V3.Y - tri.V1.Y) / (side3 - side1) ;
                   p2 = new Point3D(x2, y2, Z);
                   line.P2 = p2;
                   line_list.Add(line);

               }
               if ((Math.Sign(side2) != Math.Sign(side1)) && (Math.Sign(side2) != Math.Sign(side3)) && side2 != 0)
               {
                   x1 = tri.V2.X - side2 * (tri.V1.X - tri.V2.X) / (side1 - side2);
                   y1 = tri.V2.Y - side1 * (tri.V1.Y - tri.V2.Y) / (side1 - side2);
                   p1 = new Point3D(x1, y1, Z);
                   line.P1 = p1;
                   x2 = tri.V2.X - side2 * (tri.V3.X - tri.V2.X) / (side3 - side2) ;
                   y2 = tri.V2.Y - side2 * (tri.V3.Y - tri.V2.Y) / (side3 - side2) ;
                   p2 = new Point3D(x2, y2, Z);
                   line.P2 = p2;
                   line_list.Add(line);
               }
               if ((Math.Sign(side3) != Math.Sign(side2)) && (Math.Sign(side3) != Math.Sign(side1)) && side3 != 0)
               {
                   x1 = tri.V3.X - side3 * (tri.V1.X - tri.V3.X) / (side1 - side3);
                   y1 = tri.V3.Y - side3 * (tri.V1.Y - tri.V3.Y) / (side1 - side3);
                   p1 = new Point3D(x1, y1, Z);
                   line.P1 = p1;
                   x2 = tri.V3.X - side3 * (tri.V2.X - tri.V3.X) / (side2 - side3);
                   y2 = tri.V3.Y - side3 * (tri.V2.Y - tri.V3.Y) / (side2 - side3);
                   p2 = new Point3D(x2, y2, Z);
                   line.P2 = p2;
                   line_list.Add(line);
               }
           }
           return line_list;

       }
       /// <summary>
       /// Tao luoi cho tung mat cat
       /// </summary>
       /// <param name="polygon">Input :Danh sach diem thuoc luoi 2D</param>
       /// <param name="dm">Input: khoang cach luoi</param>
       /// <param name="wx">Chieu dai phuong x</param>
       /// <param name="wy">chieu dai phuong y</param>
       /// <param name="result">Output: Danh sach diem thuoc luoi 3D</param>
       /// <param name="z">Gia tri Z tuong ung tung lop cat</param>
       public void Create_Grid(List<REALPOINT> polygon, double dm, double wx, double wy, List<Point3D> result,double z)
        {
            detectPoint.Z = z;
            List<REALPOINT> grid = new List<REALPOINT>();
            int i = 0, j = 0, ii = 0;
            #region Buoc1
            /*
             * Buoc 1
             * Tinh cac gia tri bien X_Max, X_Min,Y_Max,Y_Min cua bien dang vat
             */
            double dz = dm;

            double x_min = Max_MinList(polygon, 1, 0);
            if (x_min < 0)
                x_min = 0;

            double x_max = Max_MinList(polygon, 1, 1);
            if (x_max > wx)
                x_max = wx;

            double y_min = Max_MinList(polygon, 0, 0);
            if (y_min < 0)
                y_min = 0;

            double y_max = Max_MinList(polygon, 0, 1);
            if (y_max > wy)
                y_max = wy;


            int x1 = (int)Math.Floor((x_max - x_min) / dm);
            int x2 = (int)Math.Floor((y_max - y_min) / dm);
            #endregion
            #region Buoc2
            /*
             * Buoc 2
             * Luu vi tri tren tuc x,y ma duong cat di qua lan luot vao cac danh sach List<POINT>x_list,y_list
             */
            List<double> x_list = new List<double>();
            List<double> y_list = new List<double>();
            double curx = 0, cury = 0;
            int x_index = 0, y_index = 0;//x_index : so vi tri khoang 1 tren truc x ; y_index :cho truc y
            int x_num = 0, y_num = 0;

            x_list.Add(curx);
            y_list.Add(cury);

            // luu vi tri tren truc y
            while (y_min - cury > 10)
            {
                cury = cury + 10;
                y_list.Add(cury);
                y_index++;
            }
            if (y_min != 0)
            {
                cury = y_min;
                y_list.Add(cury);
                y_index++;
            }
            while (y_max - cury > dm)
            {
                cury = cury + dm;
                y_list.Add(cury);

            }
            cury = y_max;
            y_list.Add(cury);
            while (wy - cury > 10)
            {
                cury = cury + 10;
                y_list.Add(cury);
            }
            if (y_max != wy)
            {
                cury = wy;
                y_list.Add(cury);
                y_num = y_list.Count;
            }
            else
            {
                y_num = y_list.Count - 1;
            }
            // Luu vi tri tren truc x
            while (x_min - curx > 10)
            {
                curx = curx + 10;
                x_list.Add(curx);
                x_index++;
            }
            if (x_min != 0)
            {
                curx = x_min;
                x_list.Add(curx);
                x_index++;
            }
            while (x_max - curx > dm)
            {
                curx = curx + dm;
                x_list.Add(curx);

            }
            curx = x_max;
            x_list.Add(curx);
            while (wx - curx > 10)
            {
                curx = curx + 10;
                x_list.Add(curx);
            }
            if (x_max != wx)
            {
                curx = wx;
                x_list.Add(curx);
                x_num = x_list.Count;
            }
            else
            {
                x_num = x_list.Count - 1;
            }
            #endregion
            /*
             * Buoc 3
             * Luu toa do cac diem cat vao danh sach List<REALPOINT>result bang cach ket hop cac gia tri trong x_list va y_list
             */
            int cdir = 0;
            int idir = 0;
            REALPOINT p = new REALPOINT();

            p.x = 0; p.y = wy;

            // gan diem dau tien cho p.x;
            j = 0;//khoi tao lai j
            i = 0;//khoi tao lai j

            p.x = x_list[0];
            ////////////////////////////////////////////////////////////////////////////////
            // Thuc hien chay theo chieu doc voi ba khoang, chay truc y
            ////////////////////////////////////////////////////////////////////////////////
            List<Point3D> TempArray = new List<Point3D>();

            while (j < x_index)
            //Khoang 1
            {
                if (cdir == 0)// huong tren -> duoi, 
                {

                    p.y = y_list[y_num - 1];
                    result.Add(new Point3D( p.x,p.y,z));
                    p.y = y_list[0];
                    result.Add(new Point3D(p.x, p.y, z));
                    ////////////////////
                    j++;
                    p.x = x_list[j];
                    cdir = 1;
                }
                else// huong duoi->tren
                {
                    p.y = y_list[0];
                    result.Add(new Point3D(p.x, p.y, z));
                    p.y = y_list[y_num - 1];
                    result.Add(new Point3D(p.x, p.y, z));
                    ////////////////////
                    j++;
                    p.x = x_list[j];
                    cdir = 0;
                }

            }
            //Khoang 2
            //j = x_index;

            int last_i = 0;
            while (j < x_index + x1)
            {
                if (cdir == 0)// huong tren-> duoi
                {
                    last_i = y_num;

                    TempArray = VertiIntersect(polygon, p.x, wy,z);
                    // thuc hien xap xep theo Y giam(tren->duoi)
                    SortYDecre(TempArray);
                    result.AddRange(InsertDetectPoint(TempArray,detectPoint));
                    TempArray.Clear();
                    /////////////////////////////
                    cdir = 1;
                    j++;// Gia tri Y khac
                    p.x = x_list[j];


                }
                else// huong duoi-> tren
                {
                    last_i = 0;
                    ///////////////////

                    TempArray = VertiIntersect(polygon, p.x, wy,z);
                    // thuc hien xap xep theo Y tang(duoi->tren)
                    SortYIncre(TempArray);
                    result.AddRange(InsertDetectPoint(TempArray, detectPoint));
                    TempArray.Clear();


                    //////////////////
                    j++;
                    p.x = x_list[j];
                    cdir = 0;
                }

            }
            // Khoang 3.
            //   j = x_index + x2;

            while (j <= x_num)
            {
                if (cdir == 0)// tren->duoi
                {
                    p.y = y_list[y_num - 1];
                    result.Add(new Point3D(p.x, p.y, z));
                    p.y = y_list[0];
                    result.Add(new Point3D(p.x, p.y, z));
                    ////////////////////

                    j++;
                    if (j > x_num - 1)// chay toi duong bien doc ben phai
                    {//doi chieu chay thanh duong doc
                        cdir = 3;//chieu tu phai qua trai
                        idir = 1;// chay ngang tu duoi len
                    }
                    else
                    {
                        p.x = x_list[j];
                        cdir = 1;
                    }

                }
                else
                {//tu duoi->tren
                    p.y = y_list[0];
                    result.Add(new Point3D(p.x, p.y, z));
                    p.y = y_list[y_num - 1];
                    result.Add(new Point3D(p.x, p.y, z));
                    ////////////////////
                    j++;
                    if (j > x_num - 1)// chay toi duong bien doc ben phai
                    {//doi chieu
                        cdir = 3;//chieu tu phai qua trai
                        idir = 0;// chay ngang tu tren->duoi
                    }
                    else
                    {
                        p.x = x_list[j];
                        cdir = 0;
                    }
                }
            }
            ////////////////////////////////////////////////////////////////////////
            /* Sau khi chay xong duong doc, tien hanh chay duong ngang gom 3 khoang .
                chi co hai truong hop
             * + Chay ngang tu duoi len
             * + Chay ngang tu tren xuong.
            */
            ////////////////////////////////////////////////////////////////////////

            j = 0;
            p.y = y_list[0];
            if (idir == 1)// chieu cat la chieu ngang tu duoi len tren
            {
                //khoang 1 
                while (j <= y_index)
                {
                    if (cdir == 3)// phai->trai
                    {
                        p.x = x_list[x_num - 1];
                        result.Add(new Point3D(p.x, p.y, z));
                        p.x = x_list[0];
                        result.Add(new Point3D(p.x, p.y, z));
                        /////////////////////////////
                        j++;
                        p.y = y_list[j];
                        cdir = 2;
                    }
                    else  //tu trai -> phai
                    {
                        p.x = x_list[0];
                        result.Add(new Point3D(p.x, p.y, z));
                        p.x = x_list[x_num - 1];
                        result.Add(new Point3D(p.x, p.y, z));
                        /////////////////////////
                        j++;
                        p.y = y_list[j];
                        cdir = 3;
                    }
                }
                // khoang 2 ,J nam gia tri tai y_index
                while (j <= y_index + x2)
                {
                    if (cdir == 3)//ngang tu phai->trai
                    {
                        last_i = x_num;
                        /////////////////
                        TempArray = HoriIntersect(polygon, p.y, wx,z);
                        // thuc hien xap xep
                        SortXDecre(TempArray);//(trai <- phai)
                        result.AddRange(InsertDetectPoint(TempArray, detectPoint));
                        TempArray.Clear();


                        /////////////////
                        j++;
                        p.y = y_list[j];
                        cdir = 2;


                    }
                    else // ngang tu trai->phai
                    {
                        last_i = 0;
                        /////////////////////
                        TempArray = HoriIntersect(polygon, p.y, wy,z);
                        // thuc hien xap xep
                        SortXIncre(TempArray);//(trai -> phai)
                        result.AddRange(InsertDetectPoint(TempArray, detectPoint));
                        TempArray.Clear();

                        /////////////////////
                        j++;
                        p.y = y_list[j];
                        cdir = 3;

                    }

                }
                // Khoang 3
                while (j < y_num)
                {
                    if (cdir == 3)//phai->trai
                    {
                        p.x = x_list[x_num - 1];
                        result.Add(new Point3D(p.x, p.y, z));
                        p.x = x_list[0];
                        result.Add(new Point3D(p.x, p.y, z));
                        ////////////////////////
                        j++;
                        if (j > y_num)
                        {//xong
                            return;
                        }
                        else
                        {
                            p.y = y_list[j];
                            cdir = 2;
                        }
                    }
                    else//trai->phai
                    {
                        p.x = x_list[0];
                        result.Add(new Point3D(p.x, p.y, z));
                        p.x = x_list[x_num - 1];
                        result.Add(new Point3D(p.x, p.y, z));
                        ////////////////////////
                        j++;
                        if (j > y_num)
                        {//doi chieu
                            return;
                        }
                        else
                        {
                            p.y = y_list[j];
                            cdir = 3;
                        }
                    }
                }


            }
            else//idir=0 chieu cat la chieu ngang tu tren xuong duoi
            {
                j = y_num;
                while (j > y_index + x2)
                {//khoang 1
                    if (cdir == 3)
                    {//ngang tu phai->trai
                        p.x = x_list[x_num - 1];
                        result.Add(new Point3D(p.x, p.y, z));
                        p.x = x_list[0];
                        result.Add(new Point3D(p.x, p.y, z));
                        ////////////////////////
                        j--;
                        p.y = y_list[j];
                        cdir = 2;
                    }
                    else
                    {//ngang tu trai->phai

                        p.x = x_list[0];
                        result.Add(new Point3D(p.x, p.y, z));
                        p.x = x_list[x_num - 1];
                        result.Add(new Point3D(p.x, p.y, z));
                        ////////////////////////
                        j--;
                        p.y = y_list[j];
                        cdir = 3;
                    }
                }

                // khoang 2 chay ngang, j nam tai x1.
                while (j > y_index)
                {//khoang 2
                    if (cdir == 3)
                    {//ngang tu phai->trai
                        last_i = x_num;
                        /////////////////
                        TempArray = HoriIntersect(polygon, p.y, wy,z);
                        // thuc hien xap xep
                        SortXDecre(TempArray);//(phai->trai)
                        result.AddRange(InsertDetectPoint(TempArray, detectPoint));
                        TempArray.Clear();
                        /////////////////
                        j--;
                        p.y = y_list[j];
                        cdir = 2;
                    }
                    else
                    {//ngang tu trai ->phai
                        last_i = 0;
                        /////////////////
                        TempArray = HoriIntersect(polygon, p.y, wy,z);
                        // thuc hien xap xep
                        SortXIncre(TempArray);//(trai -> phai)
                        result.AddRange(InsertDetectPoint(TempArray, detectPoint));
                        TempArray.Clear();

                        /////////////////
                        j--;
                        p.y = y_list[j];
                        cdir = 3;
                    }
                }

                while (j >= 0)//khoang 3
                {

                    if (cdir == 3)// phai->trai
                    {
                        p.x = x_list[x_num - 1];
                        result.Add(new Point3D(p.x, p.y, z));
                        p.x = x_list[0];
                        result.Add(new Point3D(p.x, p.y, z));
                        ////////////////////////
                        j--;
                        if (j < 0)
                        {//xong
                            return;
                        }
                        else
                        {
                            p.y = y_list[j];
                            cdir = 2;
                        }
                    }
                    else
                    {//tu trai->phai
                        p.x = x_list[0];
                        result.Add(new Point3D(p.x, p.y, z));
                        p.x = x_list[x_num - 1];
                        result.Add(new Point3D(p.x, p.y, z));
                        ////////////////////////
                        j--;
                        if (j < 0)
                        {//doi chieu
                            return;
                        }
                        else
                        {
                            p.y = y_list[j];
                            cdir = 3;
                        }
                    }

                }

            }


        }//end of function

      /* public void SortContour(List<Line3D> line3D_list,List<Line3D>outPointList)
       {

           Point3D start, end;//cac diem xac dinh cho mot doan thang
           //Point3D point = new Point3D();
           start = new Point3D(); end = new Point3D();
           Line3D line = new Line3D();
           start = line3D_list[0].P2;// diem dau contour
           end = line3D_list[0].P1;// diem cuoi contour


           point3D_list.Add(end);
           poly.Add(new REALPOINT(end.X, end.Y));

           //point = start;

           point3D_list.Add(start);
           poly.Add(new REALPOINT(start.X, start.Y));

           line3D_list[0].SetScaned(true);

           int j = 0, i = 0;


           for (i = 0; i < line3D_list.Count; i++)// duyet tao tung contour
           {
               line = new Line3D();
               line = line3D_list[i];
               if (line.NotScaned() == false)
               {
                   if (start == end)// Khi contour khep kin
                   {
                       end = line.P1;
                       start = line.p2;
                       // point = new Point3D();
                       //  point = end;

                       point3D_list.Add(end);
                       poly.Add(new REALPOINT(end.X, end.Y));

                       //point= start;
                       point3D_list.Add(start);
                       poly.Add(new REALPOINT(start.X, start.Y));

                       line.SetScaned(true);
                       i = 0;

                   }
                   else if (start == line.P1)
                   {
                       start = line.P2;
                       // point = new Point3D();
                       //  point = start;

                       point3D_list.Add(start);
                       poly.Add(new REALPOINT(start.X, start.Y));

                       line.SetScaned(true);
                       i = 0;

                   }
                   else if (start == line.P2)
                   {
                       start = line.P1;
                       // point = new Point3D();
                       // point = start;

                       point3D_list.Add(start);
                       poly.Add(new REALPOINT(start.X, start.Y));

                       line.SetScaned(true);
                       i = 0;

                   }

               }

               if (i == line3D_list.Count - 1)
               {
                   for (j = 0; j < line3D_list.Count; j++)
                   {
                       if (line3D_list[j].NotScaned() == false)
                       {
                           line = line3D_list[j];
                           end = line.P1;
                           start = line.p2;
                           // point = new Point3D();

                           // point.vertex = end;
                           point3D_list.Add(end);
                           poly.Add(new REALPOINT(end.X, end.Y));

                           //point = start;
                           point3D_list.Add(start);
                           poly.Add(new REALPOINT(start.X, start.Y));

                           line.SetScaned(true);
                           i = 1;
                           break;
                       }
                   }
               }
           }
       }
        */

        #region extra code
        /*
        public List<REALPOINT> HoriIntersect(List<REALPOINT> polygon,double dy,double wy)
        {
            List<REALPOINT> TempArray = new List<REALPOINT>();
            int i = 0,N;
            N = polygon.Count;
            
            REALPOINT start;
            REALPOINT a1 = new REALPOINT();
            start = new REALPOINT(polygon[0].x, polygon[0].y);
            TempArray.Add(new REALPOINT(0,dy));// add diem tren truc y
            for (i = 1; i < N;i++)// duyet contour de xac dinh giao diem theo phuong ngang
            {

                if (start.x != polygon[i].x || start.y != polygon[i].y)// khi chua gap diem ket thuc contour
                {
                   double first = polygon[i].y - dy;
                   double last = polygon[i - 1].y - dy;
                   if (first == 0 && last == 0)
                   {
                       if (polygon[i - 1].x != TempArray[TempArray.Count - 1].x)

                           TempArray.Add(polygon[i - 1]);
                       if (polygon[i].x != TempArray[TempArray.Count - 1].x)

                           TempArray.Add(polygon[i]);

                      

                   }
                   else if (Math.Sign(first) != Math.Sign(last))
                   {


                       a1.y = dy;
                       a1.x = ((dy - polygon[i].y) * (polygon[i].x - polygon[i - 1].x)) / (polygon[i].y - polygon[i - 1].y) + polygon[i].x;

                       if (a1.x != TempArray[TempArray.Count - 1].x)
                           TempArray.Add(a1);// them vao mang tam.
                   }
                   
                }
                if (start.x == polygon[i].x && start.y == polygon[i].y )
                {
                    double first = polygon[i].y - dy;
                    double last = polygon[i - 1].y - dy;
                    if (first == 0 && last == 0)
                    {
                        if (polygon[i - 1].x != TempArray[TempArray.Count - 1].x)

                            TempArray.Add(polygon[i - 1]);
                        if (polygon[i].x != TempArray[TempArray.Count - 1].x)

                            TempArray.Add(polygon[i]);



                    }
                    else if (Math.Sign(first) != Math.Sign(last))
                    {


                        a1.y = dy;
                        a1.x = ((dy - polygon[i].y) * (polygon[i].x - polygon[i - 1].x)) / (polygon[i].y - polygon[i - 1].y) + polygon[i].x;

                        if (a1.x != TempArray[TempArray.Count - 1].x)
                            TempArray.Add(a1);// them vao mang tam.
                    }
                    // xu li phu
                    try
                    {
                        i = i + 1;
                        start = polygon[i];
                    }
                    catch { }

                    
                }
               
           }
           TempArray.Add(new REALPOINT(wy,dy));// add diem tren truc y
           
            return TempArray;
        }
         */
        /*
         public List<REALPOINT> VertiIntersect(List<REALPOINT> polygon, double dx, double wx)
        {
            List<REALPOINT> TempArray = new List<REALPOINT>();
            int i = 0, N;
            N = polygon.Count;

            REALPOINT start;
            REALPOINT a1 = new REALPOINT();
            start = new REALPOINT(polygon[0].x, polygon[0].y);
            TempArray.Add(new REALPOINT(dx, 0));// add diem tren truc x
            for (i = 1; i < N; i++)// duyet contour de xac dinh giao diem 
            {

                if (start.x != polygon[i].x || start.y != polygon[i].y)// khi chua gap diem ket thuc contour
                {
                    double first = polygon[i].x - dx;
                    double last = polygon[i - 1].x - dx;
                    if (first == 0 && last == 0)
                    {
                        if (polygon[i - 1].y != TempArray[TempArray.Count - 1].y)// xem xet diem trung lap
                            TempArray.Add(polygon[i - 1]);

                        if (polygon[i].y != TempArray[TempArray.Count - 1].y)// xem xet diem trung lap
                            TempArray.Add(polygon[i]);

                        

                    }
                    else if (Math.Sign(first) != Math.Sign(last))
                    {


                        a1.x = dx;
                        a1.y = (dx - polygon[i].x) * (polygon[i].y - polygon[i -1].y) / (polygon[i].x - polygon[i - 1].x) + polygon[i].y;

                        if (a1.y != TempArray[TempArray.Count - 1].y)// xem xet diem trung lap
                            TempArray.Add(a1);// them vao mang tam.
                    }

                }
                if (start.y == polygon[i].y && start.x == polygon[i].x )
                {
                    double first = polygon[i].x - dx;
                    double last = polygon[i - 1].x - dx;
                    if (first == 0 && last == 0)
                    {
                        if (polygon[i - 1].y != TempArray[TempArray.Count - 1].y)// xem xet diem trung lap
                            TempArray.Add(polygon[i - 1]);

                        if (polygon[i].y != TempArray[TempArray.Count - 1].y)// xem xet diem trung lap
                            TempArray.Add(polygon[i]);



                    }
                    else if (Math.Sign(first) != Math.Sign(last))
                    {


                        a1.x = dx;
                        a1.y = (dx - polygon[i].x) * (polygon[i].y - polygon[i - 1].y) / (polygon[i].x - polygon[i - 1].x) + polygon[i].y;

                        if (a1.y != TempArray[TempArray.Count - 1].y)// xem xet diem trung lap
                            TempArray.Add(a1);// them vao mang tam.
                    }
                    // xu li phu

                    i = i + 1;
                    try
                    {
                        start = polygon[i];
                    }
                    catch
                    {
                       
                    }

                    
                }

            }
            TempArray.Add(new REALPOINT(dx, wx));// sau khi chay het mot duong thi add them diem ngoai cung 
         
            return TempArray;
        }
        */
        /*
       public void writefile(List<Point3D>array)
        
       {
           StreamWriter file = new StreamWriter("D:\\code.xyz");
           int i = 0;
           for ( i = 0; i < array.Count; i++)
           {
               file.WriteLine(array[i].X.ToString() + "\t" + array[i].Y.ToString() + "\t" + array[i].Z.ToString());
           }
           file.Close();
       }
       */
        /*
       public void Grid_Generation(List<REALPOINT> polygon, double dm, double wx, double wy, List<REALPOINT> result)
       {
           
           List<REALPOINT> grid = new List<REALPOINT>();
           int i = 0, j = 0,ii=0;
           
            
            // Buoc 1
             //Tinh cac gia tri bien X_Max, X_Min,Y_Max,Y_Min cua bien dang vat
             
           double dz = dm;

           double x_min = Max_MinList(polygon, 1, 0);
           if (x_min < 0)
               x_min = 0;

           double x_max = Max_MinList(polygon, 1, 1);
           if (x_max > wx)
               x_max = wx;

           double y_min = Max_MinList(polygon, 0, 0);
           if (y_min < 0)
               y_min = 0;

           double y_max = Max_MinList(polygon, 0, 1);
           if (y_max > wy)
               y_max = wy;
            
                              
           int x1 = (int)Math.Floor((x_max - x_min) / dm);
           int x2 = (int)Math.Floor((y_max - y_min) / dm);
            
          
           // Buoc 2
           // Luu vi tri tren tuc x,y ma duong cat di qua lan luot vao cac danh sach List<POINT>x_list,y_list
         
           List<double> x_list = new List<double>();
           List<double> y_list = new List<double>();
           double curx = 0, cury = 0;
           int x_index = 0, y_index = 0;//x_index : so vi tri khoang 1 tren truc x ; y_index :cho truc y
           int x_num=0, y_num=0;
            
           x_list.Add(curx);
           y_list.Add(cury);
                      
           // luu vi tri tren truc y
           while (y_min - cury > 10)
           {
               cury = cury + 10;
               y_list.Add(cury);
               y_index++;
           }
           if (y_min != 0)
           {
               cury = y_min;
               y_list.Add(cury);
               y_index++;
           }
           while (y_max - cury > dm)
           {
               cury = cury + dm;
               y_list.Add(cury);
               
           }
           cury = y_max;
           y_list.Add(cury);
           while (wy - cury > 10)
           {
               cury = cury + 10;
               y_list.Add(cury);
           }
           if (y_max != wy)
           {
               cury = wy;
               y_list.Add(cury);
               y_num = y_list.Count;
           }
           else
           {
               y_num = y_list.Count - 1;
           }
           // Luu vi tri tren truc x
           while (x_min - curx > 10)
           {
               curx = curx + 10;
               x_list.Add(curx);
               x_index++;
           }
           if (x_min != 0)
           {
               curx = x_min;
               x_list.Add(curx);
               x_index++;
           }
           while (x_max - curx > dm)
           {
               curx = curx + dm;
               x_list.Add(curx);
             
           }
           curx = x_max;
           x_list.Add(curx);
           while (wx - curx > 10)
           {
               curx = curx + 10;
               x_list.Add(curx);
           }
           if (x_max != wx)
           {
               curx = wx;
               x_list.Add(curx);
               x_num = x_list.Count;
           }
           else
           {
               x_num = x_list.Count - 1;
           }

            
            // Buoc 3
            // Luu toa do cac diem cat vao danh sach List<REALPOINT>result bang cach ket hop cac gia tri trong x_list va y_list
             
           int cdir = 0;
           int idir = 0;
           REALPOINT p = new REALPOINT();
            
           p.x = 0; p.y = wy;

           // gan diem dau tien cho p.x;
           j = 0;//khoi tao lai j
           i = 0;//khoi tao lai j

           p.x = x_list[0];
           ////////////////////////////////////////////////////////////////////////////////
           // Thuc hien chay theo chieu doc voi ba khoang, chay truc y
           ////////////////////////////////////////////////////////////////////////////////
           List<REALPOINT> TempArray = new List<REALPOINT>();
            
           while (j < x_index)
           //Khoang 1
           {
               if (cdir == 0)// huong tren -> duoi, 
               {

                   p.y = y_list[y_num - 1];
                   result.Add(p);
                   p.y = y_list[0];
                   result.Add(p);
                   ////////////////////
                   j++;
                   p.x = x_list[j];
                   cdir = 1;
               }
               else// huong duoi->tren
               {
                   p.y = y_list[0];
                   result.Add(p);
                   p.y = y_list[y_num - 1];
                   result.Add(p);
                   ////////////////////
                   j++;
                   p.x = x_list[j];
                   cdir = 0;
               }

           }
           //Khoang 2
           //j = x_index;
         
           int last_i=0;
           while (j < x_index + x1)
           {
               if (cdir == 0)// huong tren-> duoi
               {
                   last_i = y_num;

                   TempArray=VertiIntersect(polygon,p.x,wy);
                   // thuc hien xap xep theo Y giam(tren->duoi)
                   SortYDecre(TempArray);
                   result.AddRange(TempArray);
                   TempArray.Clear();
                   /////////////////////////////
                   cdir = 1;
                   j++;// Gia tri Y khac
                   p.x = x_list[j];
                    

               }
               else// huong duoi-> tren
               {
                   last_i = 0;
                   ///////////////////

                   TempArray = VertiIntersect(polygon, p.x, wy);
                   // thuc hien xap xep theo Y tang(duoi->tren)
                   SortYIncre(TempArray);
                   result.AddRange(TempArray);
                   TempArray.Clear();
                    
                    
                   //////////////////
                   j++;
                   p.x = x_list[j];
                   cdir = 0;
               }

           }
           // Khoang 3.
           //   j = x_index + x2;
            
           while (j <= x_num) 
           {
               if (cdir == 0)// tren->duoi
               {
                   p.y = y_list[y_num - 1];
                   result.Add(p);
                   p.y = y_list[0];
                   result.Add(p);
                   ////////////////////

                   j++;
                   if (j > x_num-1 )// chay toi duong bien doc ben phai
                   {//doi chieu chay thanh duong doc
                       cdir = 3;//chieu tu phai qua trai
                       idir = 1;// chay ngang tu duoi len
                   }
                   else
                   {
                       p.x = x_list[j];
                       cdir = 1;
                   }
                    
               }
               else
               {//tu duoi->tren
                   p.y = y_list[0];
                   result.Add(p);
                   p.y = y_list[y_num - 1];
                   result.Add(p);
                   ////////////////////
                   j++;
                   if (j >x_num-1)// chay toi duong bien doc ben phai
                   {//doi chieu
                       cdir = 3;//chieu tu phai qua trai
                       idir = 0;// chay ngang tu tren->duoi
                   }
                   else
                   {
                       p.x=x_list[j];
                       cdir = 0;
                   }
               }
           }
           ////////////////////////////////////////////////////////////////////////
            Sau khi chay xong duong doc, tien hanh chay duong ngang gom 3 khoang .
             chi co hai truong hop:
             + Chay ngang tu duoi len
             + Chay ngang tu tren xuong.
            
           ////////////////////////////////////////////////////////////////////////
            
           j = 0;
           p.y = y_list[0];
           if (idir == 1)// chieu cat la chieu ngang tu duoi len tren
           {
               //khoang 1 
               while (j <= y_index)
               {
                   if (cdir == 3)// phai->trai
                   {
                       p.x = x_list[x_num - 1];
                       result.Add(p);
                       p.x = x_list[0];
                       result.Add(p);
                       /////////////////////////////
                       j++;
                       p.y = y_list[j];
                       cdir = 2;
                   }
                   else  //tu trai -> phai
                   {
                       p.x = x_list[0];
                       result.Add(p);
                       p.x = x_list[x_num - 1];
                       result.Add(p);
                       /////////////////////////
                       j++;
                       p.y = y_list[j];
                       cdir = 3;
                   }
               }
               // khoang 2 ,J nam gia tri tai y_index
               while (j <= y_index + x2)
               {
                   if (cdir == 3)//ngang tu phai->trai
                   {
                       last_i = x_num;
                       /////////////////
                       TempArray = HoriIntersect(polygon, p.y, wx);
                       // thuc hien xap xep
                       SortXDecre(TempArray);//(trai <- phai)
                       result.AddRange(TempArray);
                       TempArray.Clear();
   
                            
                       /////////////////
                       j++;
                       p.y = y_list[j];
                       cdir = 2;
                        

                   }
                   else // ngang tu trai->phai
                   {
                       last_i = 0;
                       /////////////////////
                       TempArray = HoriIntersect(polygon,p.y,wy);
                       // thuc hien xap xep
                       SortXIncre(TempArray);//(trai -> phai)
                       result.AddRange(TempArray);
                       TempArray.Clear();
                                                
                       /////////////////////
                       j++;
                       p.y = y_list[j];
                       cdir = 3;

                   }

               }
               // Khoang 3
               while (j < y_num)
               {
                   if (cdir == 3)//phai->trai
                   {
                       p.x = x_list[x_num - 1];
                       result.Add(p);
                       p.x = x_list[0];
                       result.Add(p);
                       ////////////////////////
                       j++;
                       if (j > y_num)
                       {//xong
                           return;
                       }
                       else
                       {
                           p.y = y_list[j];
                           cdir = 2;
                       }
                   }
                   else//trai->phai
                   {
                       p.x = x_list[0];
                       result.Add(p);
                       p.x = x_list[x_num - 1];
                       result.Add(p);
                       ////////////////////////
                       j++;
                       if (j > y_num)
                       {//doi chieu
                           return;
                       }
                       else
                       {
                           p.y = y_list[j];
                           cdir = 3;
                       }
                   }
               }


           }
           else//idir=0 chieu cat la chieu ngang tu tren xuong duoi
           {
               j = y_num;
               while (j > y_index + x2)
               {//khoang 1
                   if (cdir == 3)
                   {//ngang tu phai->trai
                       p.x = x_list[x_num - 1];
                       result.Add(p);
                       p.x = x_list[0];
                       result.Add(p);
                       ////////////////////////
                       j--;
                       p.y = y_list[j];
                       cdir = 2;
                   }
                   else
                   {//ngang tu trai->phai
                        
                       p.x = x_list[0];
                       result.Add(p);
                       p.x = x_list[x_num - 1];
                       result.Add(p);
                       ////////////////////////
                       j--;
                       p.y = y_list[j];
                       cdir = 3;
                   }
               }
            
               // khoang 2 chay ngang, j nam tai x1.
               while (j > y_index)
               {//khoang 2
                   if (cdir == 3)
                   {//ngang tu phai->trai
                       last_i = x_num;
                       /////////////////
                       TempArray = HoriIntersect(polygon, p.y, wy);
                       // thuc hien xap xep
                       SortXDecre(TempArray);//(phai->trai)
                       result.AddRange(TempArray);
                       TempArray.Clear();
                       /////////////////
                       j--;
                       p.y = y_list[j];
                       cdir = 2;
                   }
                   else
                   {//ngang tu trai ->phai
                       last_i = 0;
                       /////////////////
                       TempArray = HoriIntersect(polygon, p.y, wy);
                       // thuc hien xap xep
                       SortXIncre(TempArray);//(trai -> phai)
                       result.AddRange(TempArray);
                       TempArray.Clear();
                        
                       /////////////////
                       j--;
                       p.y = y_list[j];
                       cdir = 3;
                   }
               }
              
               while (j >= 0)//khoang 3
               {
                    
                   if (cdir == 3)// phai->trai
                   {
                       p.x = x_list[x_num - 1];
                       result.Add(p);
                       p.x = x_list[0];
                       result.Add(p);
                       ////////////////////////
                       j--;
                       if (j < 0)
                       {//xong
                           return;
                       }
                       else
                       {
                           p.y = y_list[j];
                           cdir = 2;
                       }
                   }
                   else 
                   {//tu trai->phai
                       p.x = x_list[0];
                       result.Add(p);
                       p.x = x_list[x_num - 1];
                       result.Add(p);
                       ////////////////////////
                       j--;
                       if (j < 0)
                       {//doi chieu
                           return;
                       }
                       else
                       {
                           p.y = y_list[j];
                           cdir = 3;
                       }
                   }

               }
                
           }
           
        
       }//end of function
       */
        /*
   public void SlicingZ(Mesh3D mesh, double Z)
   {
       // tu vi tri Z xac dinh mang cac doan thang giao nhau.
       // Ket qua tra ve la danh sach cac duong thang.   
       //List<Line3D> linelist = new List<Line3D>();
       double side1, side2, side3;
       double x2, x1, y2, y1, z2, z1;
       Point3D p1, p2;
       Line3D line = new Line3D();
       Triangle3D tri = new Triangle3D();
       for (int i = 0; i < mesh.listModel.Count; i++)
       {
           tri = mesh.GetTriangle(i);
           side1 = tri.V1.Z - Z;
           side2 = tri.V2.Z - Z;
           side3 = tri.V3.Z - Z;
           line = new Line3D();
           if ((Math.Sign(side1) != Math.Sign(side2)) && (Math.Sign(side1) != Math.Sign(side3)) && (side1 != 0))
           {
               x1 = Math.Round(tri.V1.X - side1 * (tri.V2.X - tri.V1.X) / (side2 - side1), 2);
               y1 = Math.Round(tri.V1.Y - side1 * (tri.V2.Y - tri.V1.Y) / (side2 - side1), 2);
               z1 = Z;
               p1 = new Point3D(x1, y1, z1);
               line.P1 = p1;
               x2 = Math.Round(tri.V1.X - side1 * (tri.V3.X - tri.V1.X) / (side3 - side1), 2);
               y2 = Math.Round(tri.V1.Y - side1 * (tri.V3.Y - tri.V1.Y) / (side3 - side1), 2);
               z2 = Z;
               p2 = new Point3D(x2, y2, z2);
               line.P2 = p2;
               linelist.Add(line);

           }
           if ((Math.Sign(side2) != Math.Sign(side1)) && (Math.Sign(side2) != Math.Sign(side3)) && side2 != 0)
           {
               x1 = Math.Round(tri.V2.X - side2 * (tri.V1.X - tri.V2.X) / (side1 - side2), 2);
               y1 = Math.Round(tri.V2.Y - side1 * (tri.V1.Y - tri.V2.Y) / (side1 - side2), 2);
               z1 = Z;
               p1 = new Point3D(x1, y1, z1);
               line.P1 = p1;
               x2 = Math.Round(tri.V2.X - side2 * (tri.V3.X - tri.V2.X) / (side3 - side2), 2);
               y2 = Math.Round(tri.V2.Y - side2 * (tri.V3.Y - tri.V2.Y) / (side3 - side2), 2);
               // Z2 =Math.Round(tri.V2.Z - side2 * (tri.V3.Z - tri.V2.Z) / (side3 - side2),6);
               z2 = Z;
               p2 = new Point3D(x2, y2, z2);
               line.P2 = p2;
               linelist.Add(line);
           }
           if ((Math.Sign(side3) != Math.Sign(side2)) && (Math.Sign(side3) != Math.Sign(side1)) && side3 != 0)
           {
               x1 = Math.Round(tri.V3.X - side3 * (tri.V1.X - tri.V3.X) / (side1 - side3), 2);
               y1 = Math.Round(tri.V3.Y - side3 * (tri.V1.Y - tri.V3.Y) / (side1 - side3), 2);
               z1 = Math.Round(tri.V3.Z - side3 * (tri.V1.Z - tri.V3.Z) / (side1 - side3), 2);
               p1 = new Point3D(x1, y1, z1);
               line.P1 = p1;
               x2 = Math.Round(tri.V3.X - side3 * (tri.V2.X - tri.V3.X) / (side2 - side3), 2);
               y2 = Math.Round(tri.V3.Y - side3 * (tri.V2.Y - tri.V3.Y) / (side2 - side3), 2);
               //  Z2 =Math.Round(tri.V3.Z - side3 * (tri.V2.Z - tri.V3.Z) / (side2 - side3),6);
               z2 = Z;
               p2 = new Point3D(x2, y2, z2);
               line.P2 = p2;
               linelist.Add(line);
           }
       }


   }
   */
        #endregion extra code

    }// end of class
    
}// end of namespace

  ///// <summary>
  //     /// Tao luoi cho tung mat cat
  //     /// </summary>
  //     /// <param name="polygon">Danh sach diem thuoc luoi 2D</param>
  //     /// <param name="dm">khoang cach luoi</param>
  //     /// <param name="wx">Chieu dai phuong x</param>
  //     /// <param name="wy">chieu dai phuong y</param>
  //     /// <param name="result">Danh sach diem thuoc luoi 3D</param>
  //     /// <param name="z">Gia tri Z tuong ung tung lop cat</param>
  //     public void Create_Grid(List<REALPOINT> polygon, double dm, double wx, double wy, List<Point3D> result,double z)
  //      {

  //          List<REALPOINT> grid = new List<REALPOINT>();
  //          int i = 0, j = 0, ii = 0;
  //          #region Buoc1
  //          /*
  //           * Buoc 1
  //           * Tinh cac gia tri bien X_Max, X_Min,Y_Max,Y_Min cua bien dang vat
  //           */
  //          double dz = dm;

  //          double x_min = Max_MinList(polygon, 1, 0);
  //          if (x_min < 0)
  //              x_min = 0;

  //          double x_max = Max_MinList(polygon, 1, 1);
  //          if (x_max > wx)
  //              x_max = wx;

  //          double y_min = Max_MinList(polygon, 0, 0);
  //          if (y_min < 0)
  //              y_min = 0;

  //          double y_max = Max_MinList(polygon, 0, 1);
  //          if (y_max > wy)
  //              y_max = wy;


  //          int x1 = (int)Math.Floor((x_max - x_min) / dm);
  //          int x2 = (int)Math.Floor((y_max - y_min) / dm);
  //          #endregion
  //          #region Buoc2
  //          /*
  //           * Buoc 2
  //           * Luu vi tri tren tuc x,y ma duong cat di qua lan luot vao cac danh sach List<POINT>x_list,y_list
  //           */
  //          List<double> x_list = new List<double>();
  //          List<double> y_list = new List<double>();
  //          double curx = 0, cury = 0;
  //          int x_index = 0, y_index = 0;//x_index : so vi tri khoang 1 tren truc x ; y_index :cho truc y
  //          int x_num = 0, y_num = 0;

  //          x_list.Add(curx);
  //          y_list.Add(cury);

  //          // luu vi tri tren truc y
  //          while (y_min - cury > 10)
  //          {
  //              cury = cury + 10;
  //              y_list.Add(cury);
  //              y_index++;
  //          }
  //          if (y_min != 0)
  //          {
  //              cury = y_min;
  //              y_list.Add(cury);
  //              y_index++;
  //          }
  //          while (y_max - cury > dm)
  //          {
  //              cury = cury + dm;
  //              y_list.Add(cury);

  //          }
  //          cury = y_max;
  //          y_list.Add(cury);
  //          while (wy - cury > 10)
  //          {
  //              cury = cury + 10;
  //              y_list.Add(cury);
  //          }
  //          if (y_max != wy)
  //          {
  //              cury = wy;
  //              y_list.Add(cury);
  //              y_num = y_list.Count;
  //          }
  //          else
  //          {
  //              y_num = y_list.Count - 1;
  //          }
  //          // Luu vi tri tren truc x
  //          while (x_min - curx > 10)
  //          {
  //              curx = curx + 10;
  //              x_list.Add(curx);
  //              x_index++;
  //          }
  //          if (x_min != 0)
  //          {
  //              curx = x_min;
  //              x_list.Add(curx);
  //              x_index++;
  //          }
  //          while (x_max - curx > dm)
  //          {
  //              curx = curx + dm;
  //              x_list.Add(curx);

  //          }
  //          curx = x_max;
  //          x_list.Add(curx);
  //          while (wx - curx > 10)
  //          {
  //              curx = curx + 10;
  //              x_list.Add(curx);
  //          }
  //          if (x_max != wx)
  //          {
  //              curx = wx;
  //              x_list.Add(curx);
  //              x_num = x_list.Count;
  //          }
  //          else
  //          {
  //              x_num = x_list.Count - 1;
  //          }
  //          #endregion
  //          /*
  //           * Buoc 3
  //           * Luu toa do cac diem cat vao danh sach List<REALPOINT>result bang cach ket hop cac gia tri trong x_list va y_list
  //           */
  //          int cdir = 0;
  //          int idir = 0;
  //          REALPOINT p = new REALPOINT();

  //          p.x = 0; p.y = wy;

  //          // gan diem dau tien cho p.x;
  //          j = 0;//khoi tao lai j
  //          i = 0;//khoi tao lai j

  //          p.x = x_list[0];
  //          ////////////////////////////////////////////////////////////////////////////////
  //          // Thuc hien chay theo chieu doc voi ba khoang, chay truc y
  //          ////////////////////////////////////////////////////////////////////////////////
  //          List<Point3D> TempArray = new List<Point3D>();

  //          while (j < x_index)
  //          //Khoang 1
  //          {
  //              if (cdir == 0)// huong tren -> duoi, 
  //              {

  //                  p.y = y_list[y_num - 1];
  //                  result.Add(new Point3D( p.x,p.y,z));
  //                  p.y = y_list[0];
  //                  result.Add(new Point3D(p.x, p.y, z));
  //                  ////////////////////
  //                  j++;
  //                  p.x = x_list[j];
  //                  cdir = 1;
  //              }
  //              else// huong duoi->tren
  //              {
  //                  p.y = y_list[0];
  //                  result.Add(new Point3D(p.x, p.y, z));
  //                  p.y = y_list[y_num - 1];
  //                  result.Add(new Point3D(p.x, p.y, z));
  //                  ////////////////////
  //                  j++;
  //                  p.x = x_list[j];
  //                  cdir = 0;
  //              }

  //          }
  //          //Khoang 2
  //          //j = x_index;

  //          int last_i = 0;
  //          while (j < x_index + x1)
  //          {
  //              if (cdir == 0)// huong tren-> duoi
  //              {
  //                  last_i = y_num;

  //                  TempArray = VertiIntersect(polygon, p.x, wy,z);
  //                  // thuc hien xap xep theo Y giam(tren->duoi)
  //                  SortYDecre(TempArray);
  //                  result.AddRange(TempArray);
  //                  TempArray.Clear();
  //                  /////////////////////////////
  //                  cdir = 1;
  //                  j++;// Gia tri Y khac
  //                  p.x = x_list[j];


  //              }
  //              else// huong duoi-> tren
  //              {
  //                  last_i = 0;
  //                  ///////////////////

  //                  TempArray = VertiIntersect(polygon, p.x, wy,z);
  //                  // thuc hien xap xep theo Y tang(duoi->tren)
  //                  SortYIncre(TempArray);
  //                  result.AddRange(TempArray);
  //                  TempArray.Clear();


  //                  //////////////////
  //                  j++;
  //                  p.x = x_list[j];
  //                  cdir = 0;
  //              }

  //          }
  //          // Khoang 3.
  //          //   j = x_index + x2;

  //          while (j <= x_num)
  //          {
  //              if (cdir == 0)// tren->duoi
  //              {
  //                  p.y = y_list[y_num - 1];
  //                  result.Add(new Point3D(p.x, p.y, z));
  //                  p.y = y_list[0];
  //                  result.Add(new Point3D(p.x, p.y, z));
  //                  ////////////////////

  //                  j++;
  //                  if (j > x_num - 1)// chay toi duong bien doc ben phai
  //                  {//doi chieu chay thanh duong doc
  //                      cdir = 3;//chieu tu phai qua trai
  //                      idir = 1;// chay ngang tu duoi len
  //                  }
  //                  else
  //                  {
  //                      p.x = x_list[j];
  //                      cdir = 1;
  //                  }

  //              }
  //              else
  //              {//tu duoi->tren
  //                  p.y = y_list[0];
  //                  result.Add(new Point3D(p.x, p.y, z));
  //                  p.y = y_list[y_num - 1];
  //                  result.Add(new Point3D(p.x, p.y, z));
  //                  ////////////////////
  //                  j++;
  //                  if (j > x_num - 1)// chay toi duong bien doc ben phai
  //                  {//doi chieu
  //                      cdir = 3;//chieu tu phai qua trai
  //                      idir = 0;// chay ngang tu tren->duoi
  //                  }
  //                  else
  //                  {
  //                      p.x = x_list[j];
  //                      cdir = 0;
  //                  }
  //              }
  //          }
  //          ////////////////////////////////////////////////////////////////////////
  //          /* Sau khi chay xong duong doc, tien hanh chay duong ngang gom 3 khoang .
  //              chi co hai truong hop
  //           * + Chay ngang tu duoi len
  //           * + Chay ngang tu tren xuong.
  //          */
  //          ////////////////////////////////////////////////////////////////////////

  //          j = 0;
  //          p.y = y_list[0];
  //          if (idir == 1)// chieu cat la chieu ngang tu duoi len tren
  //          {
  //              //khoang 1 
  //              while (j <= y_index)
  //              {
  //                  if (cdir == 3)// phai->trai
  //                  {
  //                      p.x = x_list[x_num - 1];
  //                      result.Add(new Point3D(p.x, p.y, z));
  //                      p.x = x_list[0];
  //                      result.Add(new Point3D(p.x, p.y, z));
  //                      /////////////////////////////
  //                      j++;
  //                      p.y = y_list[j];
  //                      cdir = 2;
  //                  }
  //                  else  //tu trai -> phai
  //                  {
  //                      p.x = x_list[0];
  //                      result.Add(new Point3D(p.x, p.y, z));
  //                      p.x = x_list[x_num - 1];
  //                      result.Add(new Point3D(p.x, p.y, z));
  //                      /////////////////////////
  //                      j++;
  //                      p.y = y_list[j];
  //                      cdir = 3;
  //                  }
  //              }
  //              // khoang 2 ,J nam gia tri tai y_index
  //              while (j <= y_index + x2)
  //              {
  //                  if (cdir == 3)//ngang tu phai->trai
  //                  {
  //                      last_i = x_num;
  //                      /////////////////
  //                      TempArray = HoriIntersect(polygon, p.y, wx,z);
  //                      // thuc hien xap xep
  //                      SortXDecre(TempArray);//(trai <- phai)
  //                      result.AddRange(TempArray);
  //                      TempArray.Clear();


  //                      /////////////////
  //                      j++;
  //                      p.y = y_list[j];
  //                      cdir = 2;


  //                  }
  //                  else // ngang tu trai->phai
  //                  {
  //                      last_i = 0;
  //                      /////////////////////
  //                      TempArray = HoriIntersect(polygon, p.y, wy,z);
  //                      // thuc hien xap xep
  //                      SortXIncre(TempArray);//(trai -> phai)
  //                      result.AddRange(TempArray);
  //                      TempArray.Clear();

  //                      /////////////////////
  //                      j++;
  //                      p.y = y_list[j];
  //                      cdir = 3;

  //                  }

  //              }
  //              // Khoang 3
  //              while (j < y_num)
  //              {
  //                  if (cdir == 3)//phai->trai
  //                  {
  //                      p.x = x_list[x_num - 1];
  //                      result.Add(new Point3D(p.x, p.y, z));
  //                      p.x = x_list[0];
  //                      result.Add(new Point3D(p.x, p.y, z));
  //                      ////////////////////////
  //                      j++;
  //                      if (j > y_num)
  //                      {//xong
  //                          return;
  //                      }
  //                      else
  //                      {
  //                          p.y = y_list[j];
  //                          cdir = 2;
  //                      }
  //                  }
  //                  else//trai->phai
  //                  {
  //                      p.x = x_list[0];
  //                      result.Add(new Point3D(p.x, p.y, z));
  //                      p.x = x_list[x_num - 1];
  //                      result.Add(new Point3D(p.x, p.y, z));
  //                      ////////////////////////
  //                      j++;
  //                      if (j > y_num)
  //                      {//doi chieu
  //                          return;
  //                      }
  //                      else
  //                      {
  //                          p.y = y_list[j];
  //                          cdir = 3;
  //                      }
  //                  }
  //              }


  //          }
  //          else//idir=0 chieu cat la chieu ngang tu tren xuong duoi
  //          {
  //              j = y_num;
  //              while (j > y_index + x2)
  //              {//khoang 1
  //                  if (cdir == 3)
  //                  {//ngang tu phai->trai
  //                      p.x = x_list[x_num - 1];
  //                      result.Add(new Point3D(p.x, p.y, z));
  //                      p.x = x_list[0];
  //                      result.Add(new Point3D(p.x, p.y, z));
  //                      ////////////////////////
  //                      j--;
  //                      p.y = y_list[j];
  //                      cdir = 2;
  //                  }
  //                  else
  //                  {//ngang tu trai->phai

  //                      p.x = x_list[0];
  //                      result.Add(new Point3D(p.x, p.y, z));
  //                      p.x = x_list[x_num - 1];
  //                      result.Add(new Point3D(p.x, p.y, z));
  //                      ////////////////////////
  //                      j--;
  //                      p.y = y_list[j];
  //                      cdir = 3;
  //                  }
  //              }

  //              // khoang 2 chay ngang, j nam tai x1.
  //              while (j > y_index)
  //              {//khoang 2
  //                  if (cdir == 3)
  //                  {//ngang tu phai->trai
  //                      last_i = x_num;
  //                      /////////////////
  //                      TempArray = HoriIntersect(polygon, p.y, wy,z);
  //                      // thuc hien xap xep
  //                      SortXDecre(TempArray);//(phai->trai)
  //                      result.AddRange(TempArray);
  //                      TempArray.Clear();
  //                      /////////////////
  //                      j--;
  //                      p.y = y_list[j];
  //                      cdir = 2;
  //                  }
  //                  else
  //                  {//ngang tu trai ->phai
  //                      last_i = 0;
  //                      /////////////////
  //                      TempArray = HoriIntersect(polygon, p.y, wy,z);
  //                      // thuc hien xap xep
  //                      SortXIncre(TempArray);//(trai -> phai)
  //                      result.AddRange(TempArray);
  //                      TempArray.Clear();

  //                      /////////////////
  //                      j--;
  //                      p.y = y_list[j];
  //                      cdir = 3;
  //                  }
  //              }

  //              while (j >= 0)//khoang 3
  //              {

  //                  if (cdir == 3)// phai->trai
  //                  {
  //                      p.x = x_list[x_num - 1];
  //                      result.Add(new Point3D(p.x, p.y, z));
  //                      p.x = x_list[0];
  //                      result.Add(new Point3D(p.x, p.y, z));
  //                      ////////////////////////
  //                      j--;
  //                      if (j < 0)
  //                      {//xong
  //                          return;
  //                      }
  //                      else
  //                      {
  //                          p.y = y_list[j];
  //                          cdir = 2;
  //                      }
  //                  }
  //                  else
  //                  {//tu trai->phai
  //                      p.x = x_list[0];
  //                      result.Add(new Point3D(p.x, p.y, z));
  //                      p.x = x_list[x_num - 1];
  //                      result.Add(new Point3D(p.x, p.y, z));
  //                      ////////////////////////
  //                      j--;
  //                      if (j < 0)
  //                      {//doi chieu
  //                          return;
  //                      }
  //                      else
  //                      {
  //                          p.y = y_list[j];
  //                          cdir = 3;
  //                      }
  //                  }

  //              }

  //          }


  //      }//end of function